﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Windows.Input;

namespace PeerComLink
{
    [DataContract]
    [Serializable]
    public class Member : INotifyPropertyChanged
    {
        string _displayName;

        [DataMember]
        public string DisplayName
        {
            get
            {
                return _displayName;
            }
            set
            {
                _displayName = value;
                OnPropertyChanged("DisplayName");
            }
        }

        [DataMember]
        public Guid ID { get; set; }

        public string RemoteIP { get; set; }

        public static Member Create()
        {
            return new Member
            {
                ID = Guid.NewGuid(),
                DisplayName = "NewUser"
            };
        }
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }

    public class MemberCommand : ICommand
    {
        MemberStatus _memberStatus;
        public MemberCommand(MemberStatus memberStatus)
        {
            _memberStatus = memberStatus;
        }

        bool ICommand.CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        void ICommand.Execute(object parameter)
        {
            switch (_memberStatus.State)
            {
                case MemberStatus.MemberState.Connected:
                    App.RunningData.EndCall(_memberStatus);
                    break;
                case MemberStatus.MemberState.RequestReceived:
                    App.RunningData.AcceptCall(_memberStatus);
                    break;
                case MemberStatus.MemberState.RequestSent:
                    App.RunningData.EndCall(_memberStatus);
                    break;
                case MemberStatus.MemberState.Standby:
                    App.RunningData.InitiateCall(_memberStatus);
                    break;
            }
        }
    }

    public class MemberStatus : INotifyPropertyChanged
    {


        public MemberStatus()
        {
            Action = new MemberCommand(this);
        }

        public Member Recepient { get; set; }

        public DateTime StatusLastUpdated { get; private set; }

        MemberState _state;

        public MemberState State
        {
            get
            {
                return _state;
            }
            set
            {
                _state = value;
                StatusLastUpdated = DateTime.UtcNow;
                OnPropertyChanged("State");
                OnPropertyChanged("ActionText");
                OnPropertyChanged("CanStartCall");
            }
        }
        public string ActionText
        {
            get
            {
                switch (State)
                {
                    case MemberState.Connected:
                        return "Disconnect";
                    case MemberState.RequestReceived:
                        return "Accept";
                    case MemberState.RequestSent:
                        return "Cancel";
                    case MemberState.Standby:
                        return "Connect";
                    default:
                        return "";
                }
            }
        }



        public enum MemberState
        {
            NotSet,
            RequestSent,
            RequestReceived,
            Connected,
            Standby
        }

        public bool CanStartCall
        {
            get
            {
                return State != MemberState.Connected;
            }
        }

        public ICommand Action { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}
